﻿using System;
using System.Collections.Generic;
using System.Text;
using MDSAdministration;

namespace MDSAdministration
{
    class CodeBuilder
    {
        public string Build(List<mdsModel> models)
        {
            string code = "";
            if (models != null && models.Count > 0)
            {
                foreach (var m in models)
                {
                    StringBuilder baseClass = new StringBuilder();
                    baseClass.Append("public class mdsType" + Environment.NewLine);
                    baseClass.Append("{" + Environment.NewLine);
                    baseClass.Append("\tpublic Identifier Id;" + Environment.NewLine);
                    baseClass.Append("}" + Environment.NewLine);

                    code += baseClass;

                    StringBuilder createClass = new StringBuilder();

                    createClass.Append("public class mdsCreator" + Environment.NewLine);
                    createClass.Append("{" + Environment.NewLine);
                    createClass.Append("\tpublic static mdsType FactoryMethod(string TypeName)" + Environment.NewLine);
                    createClass.Append("\t{" + Environment.NewLine);
                    createClass.Append("\t\tswitch(TypeName)" + Environment.NewLine);
                    createClass.Append("\t\t{" + Environment.NewLine);

                    code += "//-------------" + m.Description + "-------------" + Environment.NewLine;
                    
                    foreach (var v in m.Versions)
                    {
                        foreach (var en in v.Entities)
                        {
                            createClass.Append(creatorFactoryCaseStatement(en.Description, "\t\t\t"));

                            StringBuilder sb = new StringBuilder();
                            sb.Append(String.Format("public class {0}: mdsType", en.Description) + Environment.NewLine);
                            sb.Append("{" + Environment.NewLine);

                            foreach (var a in en.Attributes)
                            {
                                if (a.MemberType == Constants.ATTRIBUTE_TYPE_LEAF)
                                {
                                    string type = a.DataType;
                                    if ("Text" == a.DataType)
                                    {
                                        type = "string";
                                    }
                                    else if ("Number" == a.DataType)
                                    {
                                        type = "int";
                                    }
                                    else if ("Link" == a.DataType)
                                    {
                                        type = "string";
                                    }

                                    sb.Append(String.Format("\tpublic {0} {1} {{ get; set; }}", type, a.Description) + Environment.NewLine);
                                }
                            }

                            sb.Append("}" + Environment.NewLine);

                            code += (sb.ToString() + Environment.NewLine);
                        }
                    }

                    createClass.Append("\t\t}" + Environment.NewLine);
                    createClass.Append("\t\treturn null;" + Environment.NewLine);
                    createClass.Append("\t}" + Environment.NewLine);
                    createClass.Append("}" + Environment.NewLine);

                    code += createClass.ToString();
                }
            }
            return code;
        }

        public string creatorFactoryCaseStatement(string TypeName, string indentation)
        {
            string caseDetails = String.Format("{0}case \"{1}\":", indentation, TypeName) + Environment.NewLine;
            caseDetails += indentation + "{" + Environment.NewLine;
            caseDetails += String.Format("{0}\treturn new {1}();", indentation, TypeName) + Environment.NewLine; 
            caseDetails += indentation + "}" + Environment.NewLine; 
            return caseDetails;
        }
    }
}
